﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Kaskelot.SP.UI.Analys.Data;
using Kaskelot.SP.UI.Analys.Domain;
using Kaskelot.SP.UI.Analys.ViewModel;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Data.DataFilter;
using Telerik.Windows.Data;
using System.Collections.ObjectModel;

namespace Kaskelot.SP.UI.Analys.Controls
{
    public partial class QueryBuilder : UserControl
    {
        public event EventHandler<GenericEventArgs<Query>> FilterReady = delegate { };
        public event EventHandler<GenericEventArgs<List<Field>>> FieldsUpdated = delegate { };
        internal static string GlobalQueriesText = "Delade urval:";
        internal static string PersonalQueriesHeading = "Dina urval:";
        private Guid currentQueryId;

        private ViewModel.CheckboxQueryBuilderViewModel checkBoxQueryBuilderViewModel;

        public QueryBuilder()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(QueryBuilder_Loaded);
            //TreeContainer.FieldsUpdated += new EventHandler<GenericEventArgs<List<Field>>>(TreeContainer_FieldsUpdated);
        }

        //void TreeContainer_FieldsUpdated(object sender, GenericEventArgs<List<Field>> e)
        //{
        //    FieldsUpdated(this, e);
        //}

        public void QueryBuilder_Loaded(object source, RoutedEventArgs args)
        {
            //TreeContainer.EntitiesSelected += new EventHandler<GenericEventArgs<List<Entity>>>(TreeContainer_EntitiesSelected);

            this.Query.FilterReady += Query_FilterReady;
            this.Query.FieldsUpdated += Query_FieldsUpdated;

            GetEntities(delegate() 
            {
                this.Query.DataContext = this.checkBoxQueryBuilderViewModel;
                LoadQueries();
            });
        }

        void Query_FieldsUpdated(object sender, GenericEventArgs<List<Field>> e)
        {
            FieldsUpdated(sender, e);
        }

        void Query_FilterReady(object sender, GenericEventArgs<Query> e)
        {
            FilterReady(sender, e);
        }

        private void GetEntities(Action onSuccess)
        {
            AnalyseServiceWrapper.Instance.GetEntities(
                //Success
                delegate(ObservableCollection<ViewModel.Entity> entities)
                {
                    this.checkBoxQueryBuilderViewModel= new ViewModel.CheckboxQueryBuilderViewModel();
                    //this.checkBoxQueryBuilderViewModel.PropertyChanged += checkBoxQueryBuilderViewModel_PropertyChanged;
                    this.checkBoxQueryBuilderViewModel.Query.Entities = entities.ToList();
                    onSuccess();
                },
                //Error
                delegate(Exception ex)
                {
                    ErrorHandler.Instance.HandleError(ex);
                });
        }

        //void checkBoxQueryBuilderViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        //{
            //if (e.PropertyName == "Query")
            //{
            //    FieldsUpdated(this, new GenericEventArgs<List<Field>>(this.checkBoxQueryBuilderViewModel.Query.DisplayFields));
            //}
            //if (e.PropertyName == "SelectionModeSelectQuery")
            //{
            //    ResetQuery();
            //}
        //}

        private void LoadQueries()
        {
            //SavedQueryChoice.Items.Clear();
            this.checkBoxQueryBuilderViewModel.SavedQueries.Clear();
            AnalyseServiceWrapper.Instance.GetPersonalQueries(
                (List<Query> result) =>
                {
                    this.checkBoxQueryBuilderViewModel.SavedQueries.Add(new Query { ID = 0, Name = GlobalQueriesText, Entities = this.checkBoxQueryBuilderViewModel.Query.Entities, Filters = new List<IFilterPart>() });
                    result.Where(q => q.IsPersonal == false).ToList().ForEach(delegate(Query q)
                    {
                        this.checkBoxQueryBuilderViewModel.SavedQueries.Add(q);
                    });
                    this.checkBoxQueryBuilderViewModel.SavedQueries.Add(new Query { ID = 0, Name = PersonalQueriesHeading, Entities = this.checkBoxQueryBuilderViewModel.Query.Entities, Filters = new List<IFilterPart>() });
                    result.Where(q => q.IsPersonal == true).ToList().ForEach(delegate(Query q)
                    {
                        this.checkBoxQueryBuilderViewModel.SavedQueries.Add(q);
                    });
                    //SavedQueryChoice.SelectionChanged += new Telerik.Windows.Controls.SelectionChangedEventHandler(SavedQueryChoice_SelectionChanged);
                },
                (Exception ex) =>
                {
                    ErrorHandler.Instance.HandleError(ex);
                });
        }

        private void SavedQueryChoice_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
        {
            //if (SavedQueryChoice.SelectedItem == null)
            //    return;

            //Query selection = SavedQueryChoice.SelectedItem as Query;

            //if (selection.Name == GlobalQueriesText || selection.Name == PersonalQueriesHeading)
            //{
            //    SavedQueryChoice.SelectedItem = null;
            //    return;
            //}

            //if (selection != null)
            //{
            //    //TreeContainer.Reset(delegate()
            //    //{
            //    //    FilterContainer.Reset();
            //    //    FilterContainer.SetDataSource(selection.Entities);
            //    //    TreeContainer.SetCheckedItems(selection.Entities, selection.DisplayFields);
            //    //    FilterContainer.SetFilters(selection.Filters);
            //    //    FieldsUpdated(this, new GenericEventArgs<List<Field>>(selection.DisplayFields));
            //    //});
            //}
        }

        void TreeContainer_EntitiesSelected(object sender, GenericEventArgs<List<Entity>> e)
        {
            //FilterContainer.SetDataSource(e.Item);
        }

        private void GoButton_Click(object sender, RoutedEventArgs e)
        {
            Query query = this.checkBoxQueryBuilderViewModel.Query;
            //query.Filters = FilterContainer.GetCurrentFilters();
            //query.DisplayFields = TreeContainer.GetCurrentFields();
            //query.Entities = TreeContainer.GetCurrentEntities();
            FieldsUpdated(this, new GenericEventArgs<List<Field>>(query.DisplayFields));
            FilterReady(this, new GenericEventArgs<Query>(query));

            ErrorHandler.Instance.ClearError();
        }

        private void ResetButton_Click(object sender, RoutedEventArgs e)
        {
            ErrorHandler.Instance.ClearError();

            ResetQuery();
        }

        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            object content;
            Query currentQuery = this.checkBoxQueryBuilderViewModel.Query;
            if (this.checkBoxQueryBuilderViewModel.SelectionModeSelectQuery)
            {
                if (currentQuery.IsPersonal == false && UserInfo.Instance.HasAdminPriveleges == false)
                {
                    RadWindow.Alert("You have insufficient permissions to save global queries, use Save as to save your own copy of the query.");
                    return;
                }

                bool considerAsNew = currentQuery.Name == GlobalQueriesText;

                SavePrompt prompt = new SavePrompt();
                prompt.AdminPart.Visibility = UserInfo.Instance.HasAdminPriveleges ? Visibility.Visible : Visibility.Collapsed;
                prompt.cbIsGlobal.IsChecked = currentQuery.IsPersonal == false;
                prompt.QueryID = currentQuery.ID;
                content = prompt;

                DialogParameters param = new DialogParameters
                {
                    Content = content,
                    DefaultPromptResultValue = considerAsNew || (UserInfo.Instance.HasAdminPriveleges == false && currentQuery.IsPersonal == false) ? string.Empty : currentQuery.Name,
                    Header = "Kaskelot",
                    Closed = new EventHandler<WindowClosedEventArgs>(OnSavePromptClosed)
                };
                RadWindow.Prompt(param);
            }
            else
                SaveAsButton_Click(sender, e);
        }

        private void OnSavePromptClosed(object sender, WindowClosedEventArgs e)
        {
            bool isGlobal = false;
            int id = 0;
            var innerContentControl = ((RadConfirm)(RadConfirm)((RadWindow)sender).Content).Content;

            var saveprompt = innerContentControl as SavePrompt;
            isGlobal = saveprompt != null && saveprompt.cbIsGlobal.IsChecked.HasValue && saveprompt.cbIsGlobal.IsChecked.Value == true;
            id = saveprompt != null ? saveprompt.QueryID : 0;

            if (e.DialogResult == true)
            {
                if (!string.IsNullOrEmpty(e.PromptResult))
                {
                    Query query = this.checkBoxQueryBuilderViewModel.Query;
                    //query.Filters = FilterContainer.GetCurrentFilters();
                    //query.DisplayFields = TreeContainer.GetCurrentFields();
                    //query.Entities = TreeContainer.GetCurrentEntities();
                    query.Name = e.PromptResult;
                    query.ID = id;

                    ErrorHandler.Instance.ClearError();

                    if (isGlobal == false)
                    {
                        AnalyseServiceWrapper.Instance.SavePersonalQuery(query,
                            (string result) =>
                            {
                                LoadQueries();
                                RadWindow.Alert(result);
                            },
                            (Exception ex) =>
                            {
                                ErrorHandler.Instance.HandleError(ex);
                            });
                    }
                    else
                    {
                        AnalyseServiceWrapper.Instance.SaveGlobalQuery(query,
                            (string result) =>
                            {
                                LoadQueries();
                                RadWindow.Alert(result);
                            },
                            (Exception ex) =>
                            {
                                ErrorHandler.Instance.HandleError(ex);
                            });
                    }
                }
            }
        }

        private void SaveAsButton_Click(object sender, RoutedEventArgs e)
        {
            object content;

            if (UserInfo.Instance.HasAdminPriveleges)
            {
                SavePrompt prompt = new SavePrompt();
                content = prompt;
            }
            else
                content = "Save personal query";

            DialogParameters param = new DialogParameters
            {
                Content = content,
                Header = "Kaskelot",
                Closed = new EventHandler<WindowClosedEventArgs>(OnSavePromptClosed)
            };
            RadWindow.Prompt(param);
        }

        private void ResetQuery()
        {
            GetEntities(delegate()
            {
                this.Query.DataContext = this.checkBoxQueryBuilderViewModel;
                LoadQueries();
            });
            FilterReady(this, new GenericEventArgs<Query>(null));
            FieldsUpdated(this, new GenericEventArgs<List<Field>>(new List<Field>()));
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            //Query currQuery = (Query)SavedQueryChoice.SelectedItem;
            //if (currQuery.Name == GlobalQueriesText)
            //{
            //    RadWindow.Alert("You need to select a query to delete");
            //    return;
            //}
            //if (currQuery.IsPersonal == false && UserInfo.Instance.HasAdminPriveleges == false)
            //{
            //    RadWindow.Alert("You have insufficient permissions to delete global queries");
            //    return;
            //}

            //DialogParameters param = new DialogParameters
            //{
            //    Content = "Are you sure you want to delete " + currQuery.Name + "?",
            //    Header = "PIMS",
            //    Closed = new EventHandler<WindowClosedEventArgs>(OnDeletePromptClosed)
            //};
            //currentQueryId = currQuery.ID;
            //RadWindow.Confirm(param);
        }

        //private void OnDeletePromptClosed(object sender, WindowClosedEventArgs e)
        //{
        //    if (e.DialogResult.HasValue && e.DialogResult.Value == true)
        //    {
        //        AnalyseServiceWrapper.Instance.DeleteQuery(currentQueryId,
        //            (string message) =>
        //            {
        //                LoadQueries();
        //                RadWindow.Alert(message);
        //            },
        //            (Exception ex) =>
        //            {
        //                ErrorHandler.Instance.HandleError(ex);
        //            });
        //    }
        //}   
    }

    public class ComboStyleSelector : StyleSelector
    {
        public override Style SelectStyle(object item, DependencyObject container)
        {
            Query q = item as Query;
            if (q != null)
            {
                if (q.Name == QueryBuilder.PersonalQueriesHeading || q.Name == QueryBuilder.GlobalQueriesText)
                    return Application.Current.Resources["HeadingStyle"] as Style;
            }

            return base.SelectStyle(item, container);
        }
    }
}
